﻿/* Copyright © Hauer Engineering 2012 */


// ERD Graph object
var ERDGraph = function (options)
{
    var ctx = this;

    // default options
    var defaultOptions =
    {
        // element (and its descendants) to which to apply ERD Graph properties
        el: null,
        // view model
        viewModel: null,
        // DOM related options
        DOM:
            {
                // container for graph nodes
                containerSelector: '.erd-graph'
            }
    };

    // extend default options with user-defined options
    if (options)
        $.extend(true, defaultOptions, options);

    // extend existing ERD functionality
    ctx.extend_ERD();

    // set render mode: CANVAS/SVG/VML
    jsPlumb.setRenderMode(jsPlumb.SVG);

    // jsPlumb can handle the DOM OnLoad event for a variety of libraries using jsPlumb.bind('ready', function (){...});

    // create jsPlumb instance
    ctx.graphInstance = jsPlumb.getInstance();

    // subscribe to events
    ERDEntity.events.add_removingFromGraph(defaultOptions.viewModel,
        function (event, args)
        {
            var entity = args.entity;
            
            // remove entity from graph
            entity.removeFromGraph();
        });

    ERDEntity.events.add_addedToGraph(defaultOptions.viewModel,
        function (event, args)
        {
            var entity = args.entity;

            // add entity to graph
            entity.addToGraph(ctx);
        });
}
ERDGraph.prototype =
    {
        extend_ERD: function ()
        {
            this.extend_ERDViewModel();
            this.extend_ERDEntity();
        },

        extend_ERDViewModel: function()
        {
            var ctx = this;

            ERDViewModel.prototype.graphGetEntityById = function (id)
            {
                var model = this;
                var entity = null;

                $(model.fk.domains()).each(function ()
                {
                    if (this.UI.graphVisible())
                    {
                        $(this.fk.entities()).each(function ()
                        {
                            if (this.attr.Id() == id && this.UI.graphVisible())
                            {
                                entity = this;
                            }
                        });
                    }
                });

                return entity;
            }
        },

        extend_ERDEntity: function ()
        {
            var ctx = this;

            ERDEntity.prototype.addToGraph = function (graph)
            {
                var entity = this;
                var entityElId = entity.UI.entityElId();

                // current graph instance
                entity.graph = graph;

                // create graph endpoint
                if ($('#' + entityElId).length > 0)
                {                    
                    entity.graphEndpoint = graph.graphInstance.addEndpoint(entityElId);
                    graph.graphInstance.draggable(entityElId,
                        {
                            containment: 'erd-graph'
                        });

                    // for each relation create connection
                    $(entity.fk.relations()).each(function ()
                    {
                        var entityId = entity.attr.Id() == this.attr.DomainEntityAId() ? this.attr.DomainEntityBId() : this.attr.DomainEntityAId();

                        // get the other entity of the relation
                        var entity2 = entity.domain.model.graphGetEntityById(entityId);

                        if (entity2 != null)
                        {
                            graph.graphInstance.connect(
                                {
                                    source: entity.UI.entityElId(),
                                    target: entity2.UI.entityElId()
                                });
                        }
                    });
                }
            };

            ERDEntity.prototype.removeFromGraph = function ()
            {
                var entity = this;

                // delete graph endpoint
                if (entity.graph && entity.graph.graphInstance)
                {
                    entity.graph.graphInstance.deleteEndpoint(entity.graphEndpoint);
                }
            }
        }
    };
